home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
telecomm
/
sticpsrc.lzh
/
SOURCE.ARC
/
NR7.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-10-06
|
29KB
|
1,223 lines
/* NET/ROM level 7 processing (user command interpreter) */
#include <stdio.h>
#include <ctype.h>
#include "global.h"
#include "mbuf.h"
#include "iface.h"
#include "timer.h"
#include "ax25.h"
#include "lapb.h"
#include "netrom.h"
#include "cmdparse.h"
#include "netuser.h"
static struct mbuf *nr7id();
static struct nr_user *find_nr_axuser();
static void del_nr_user(),nr7_send(),nr7_execute();
static void nr7_rxn(),nr7_stnr(),nr7_crx(),nr7_ctx(),nr7_rxa(),nr7_state();
static struct nr_user *nr_users; /* users connected to the NET/ROM */
static struct nr_user *nr_curusr; /* requesting user */
extern struct mbuf *recv_ax25();
extern char hostname[],version[];
static char nrlog[] = "%s %s - %s";
static char nrconlog[] = "Connected NET/ROM";
static char nrdwnlog[] = "NET/ROM downlink %s";
static char nrcirlog[] = "NET/ROM circuit ok";
static char nrciflog[] = "NET/ROM circuit ab";
static char nrconnect[] = "Connected to %s\r";
static char nrfailure[] = "Failure with %s\r";
static char nrbusy[] = "Busy from %s\r";
static char nrifunknown[] = "Interface unknown\r";
static char nrnodebusy[] = "Node busy\r";
static char nrinvalid[] = "Invalid callsign\r";
/* This is the default receive upcall function, used when
* someone else connects to us and sends a pid=Text packet.
* This will start a session with the NET/ROM command interpreter.
*/
void
ax_incom(axp,cnt)
register struct ax25_cb *axp;
int16 cnt;
{
register struct nr_user *nru;
/* check if NET/ROM handling is supported here */
if(axp->interface->nriface == NULLNRIFACE || /* not NET/ROM iface */
!axp->interface->nriface->uplink || /* no uplinks here */
!ismycall(&axp->addr.source)){ /* not proper callsign */
#if 0
tnc_state(axp,DISCONNECTED,CONNECTED,LAPBCONN);/* try interactive */
#else
disc_ax25(axp); /* throw him out */
#endif
return;
}
/* register new NET/ROM user */
if((nru = find_nr_axuser(axp,NRU_UP)) != NULLNRUSER ||
(nru = (struct nr_user *) calloc(1,sizeof(struct nr_user))) == NULLNRUSER) {
disc_ax25(axp);
return;
}
if((nru->next = nr_users) != NULLNRUSER)
nru->next->prev = nru;
nr_users = nru;
nru->ax25_cb[NRU_UP] = axp;
nru->iface = axp->interface;
axp->paclen = 256; /* NET/ROM always has paclen=256 */
axp->window = 1; /* use tight flow control */
axp->r_upcall = nr7_rxa;
axp->s_upcall = nr7_state;
log_ax(axp,nrconlog);
nr7_rxa(axp,cnt); /* pass first packet to interpreter */
}
/* receive upcall handler for AX.25 Text packets incoming on interface call */
static void
nr7_rxa(axp,cnt)
struct ax25_cb *axp;
int16 cnt;
{
register struct nr_user *nru;
struct mbuf *bp;
char inbuf[80];
struct mbuf *recvl_ax25();
if ((nru = find_nr_axuser(axp,NRU_UP)) == NULLNRUSER) {
disc_ax25(axp); /* who are you? */
return;
}
while((bp = recvl_ax25(axp,0)) != NULLBUF){ /* get a line of text */
inbuf[pullup(&bp,inbuf,sizeof(inbuf) - 1)] = '\0';
free_p(bp);
nr7_execute(nru,inbuf); /* execute the command */
}
}
/* state-change upcall handler to be used once Text packets for the NET/ROM
* command interpreter have been received.
* it is also used as a DM-sender for the AX.25 port for downlinks
*/
static void
nr7_state(axp,old,new,msg)
struct ax25_cb *axp;
int old,new,msg;
{
register struct nr_user *nru;
switch (new)
{
case CONNECTED:
if (msg == LAPBCONN) /* can only be the AX.25 port */
axp->state = DISCONNECTED; /* refuse incoming connections */
/* also do processing for DISCONNECTED */
case DISCONNECTED:
if ((nru = find_nr_axuser(axp,NRU_UP)) == NULLNRUSER)
break;
del_nr_user(nru);
break;
}
}
#ifdef NETROM4
/* receive upcall hand;
c for NET/ROM Info */
void
nr7_rxnr(circ,pkcnt)
register struct nr_circ *circ;
int16 pkcnt;
{
register struct nr_user *nru;
char tmp1[10],tmp2[10];
/* register a new user */
if ((nru = (struct nr_user *) circ->user) != NULLNRUSER ||
(nru = (struct nr_user *) calloc(1,sizeof(struct nr_user))) == NULLNRUSER) {
nr4_close(circ);
return;
}
if ((nru->next = nr_users) != NULLNRUSER)
nru->next->prev = nru;
nr_users = nru;
nru->nrcirc[NRU_UP] = circ;
nru->iface = nr_lap;
circ->r_upcall = nr7_rxn;
circ->s_upcall = nr7_stnr;
circ->user = (char *) nru;
pax25(tmp1,&circ->dnode);
pax25(tmp2,&circ->suser);
log_msg(nrlog,tmp1,tmp2,nrconlog);
nr7_rxn(circ,pkcnt); /* first packet to interpreter */
}
/* receive upcall handler for NET/ROM info after first packet received */
static void
nr7_rxn (circ,pkcnt)
register struct nr_circ *circ;
int16 pkcnt;
{
register struct nr_user *nru;
struct mbuf *bp;
char inbuf[80];
struct mbuf *pullline();
if ((nru = (struct nr_user *) circ->user) == NULLNRUSER) {
nr4_close(circ);
return;
}
circ->rxq = nr4_recv(circ,pkcnt); /* receive all packets and append */
while((bp = pullline(&circ->rxq,0)) != NULLBUF){ /* get a line of text */
inbuf[pullup(&bp,inbuf,sizeof(inbuf) - 1)] = '\0';
free_p(bp);
nr7_execute(nru,inbuf); /* execute the command */
}
}
/* NET/ROM state-change upcall hand;er to be used once packets received over
the NET/ROM level 4 circuit */
static void
nr7_stnr(circ,old,new)
struct nr_circ *circ;
int old,new;
{
register struct nr_user *nru;
switch (new)
{
case NR4STDISC:
if ((nru = (struct nr_user *) circ->user) == NULLNRUSER)
break;
del_nr_user(nru);
break;
}
}
#endif
/* commands available from NET/ROM */
static int nr7_conn(),nr7_info(),nr7_mheard(),nr7_nodes(),nr7_parms(),
nr7_ports(),nr7_routes(),nr7_users();
static struct cmds netromcmds[] = {
#ifdef NETROM4
"CONNECT", nr7_conn, 0, NULLCHAR, NULLCHAR,
#endif
"INFO", nr7_info, 0, NULLCHAR, NULLCHAR,
"MHEARD", nr7_mheard, 0, NULLCHAR, NULLCHAR,
"NODES", nr7_nodes, 0, NULLCHAR, NULLCHAR,
#ifdef NR7PARMS
"PARMS", nr7_parms, 0, NULLCHAR, NULLCHAR,
#endif
"PORTS", nr7_ports, 0, NULLCHAR, NULLCHAR,
"ROUTES", nr7_routes, 0, NULLCHAR, NULLCHAR,
#ifdef NETROM4
"USERS", nr7_users, 0, NULLCHAR, NULLCHAR,
#endif
NULLCHAR, NULLFP, 0, NULLCHAR, NULLCHAR
};
/* execute a NET/ROM command already in a line buffer */
static void
nr7_execute(nru,inbuf)
register struct nr_user *nru;
char inbuf[];
{
char *p;
struct mbuf *bp;
register struct cmds *cm;
/* when a command comes in, terminate any pending downlinks */
/* first clear the "user" fields to suppress messages */
if (nru->ax25_cb[NRU_DOWN] != NULLAX25) {
nru->ax25_cb[NRU_DOWN]->user = NULLCHAR;
disc_ax25(nru->ax25_cb[NRU_DOWN]);
nru->ax25_cb[NRU_DOWN] = NULLAX25;
}
if (nru->nrcirc[NRU_DOWN] != NULLNRCIRC) {
nru->nrcirc[NRU_DOWN]->user = NULLCHAR;
nr4_close(nru->nrcirc[NRU_DOWN]);
nru->nrcirc[NRU_DOWN] = NULLNRCIRC;
}
rip(inbuf); /* strip CR and LF chars */
for(p = inbuf; *p != '\0'; p++) /* convert rest to UPPER case */
*p = toupper(*p);
nr_curusr = nru; /* set current user */
if (inbuf[0] != '\0' && /* don't parse empty lines */
(index(inbuf,'$') != NULLCHAR || /* don't parse lines with $ */
cmdparse(netromcmds,inbuf) < 0)) /* parse a NET/ROM cmd */
{
bp = nr7id();
append(&bp,qstring("Invalid command ("));
for (cm = netromcmds; cm->name != NULLCHAR; cm++) {
append(&bp,qstring(cm->name));
append(&bp,qstring(((cm+1)->name != NULLCHAR)? " ":")\r"));
}
nr7_send(bp); /* send the error message */
if (++(nru->errors) >= 3) { /* too many errors? */
if (nru->ax25_cb[NRU_UP] != NULLAX25)
close_ax25(nru->ax25_cb[NRU_UP]);
if (nru->nrcirc[NRU_UP] != NULLNRCIRC)
nr4_close(nru->nrcirc[NRU_UP]);
}
} else {
nru->errors = 0; /* reset errorcnt on good command */
}
nr_curusr = NULLNRUSER; /* end current user */
}
#ifdef NETROM4
/* AX.25 receive upcall hand;
c */
static void
nr7_arx(axp,cnt)
register struct ax25_cb *axp;
int16 cnt;
{
registe